#![allow(dead_code)]

use std::collections::HashMap;
use hyper::http::{Method, Request, Uri};
use mlua::{UserData, UserDataMethods};
use hyper::Body;
use std::str::FromStr;
use crate::util::util::to_static_str;


//======================== HttpRequest =============================================================
#[derive(serde::Deserialize,Clone,serde::Serialize,Default)]
pub struct HttpRequest {
    pub method:String,
    pub url:String,
    pub headers:HashMap<String,String>,
    pub body:&'static str,
    pub timeout:u64,
}
impl HttpRequest{
    pub fn get_method(&self)->Method{
        match self.method.as_str() {
            "POST"=>Method::POST,
            _=>Method::GET,
        }
    }
    pub fn to_request(&self)->Result<Request<Body>,String>{
        let url = match Uri::from_str(self.url.as_str()) {
            Ok(o)=>o,
            Err(e)=>{
                return Err(e.to_string())
            }
        };
        let mut request = Request::builder()
            .method(self.get_method())
            .uri(url);
        for (key,value) in self.headers.iter() {
            request = request.header(key.as_str(), value.as_str());
        }
        match request.body(Body::from(self.body.as_bytes())) {
            Ok(o)=>Ok(o),
            Err(e)=>Err(e.to_string()),
        }
    }
    pub fn get_timeout(&self)->tokio::time::Duration{
        if self.timeout <= 0{
            return tokio::time::Duration::from_secs(60)
        }
        tokio::time::Duration::from_secs(self.timeout)
    }
}
impl UserData for HttpRequest {
    fn add_methods<'lua, M: UserDataMethods<'lua, Self>>(methods: &mut M) {
        methods.add_method_mut("set_method",|_,hr,m:String|{
            hr.method = m;
            Ok(())
        });
        methods.add_method_mut("set_timeout",|_,hr,timeout:u64|{
            hr.timeout = timeout;
            Ok(())
        });
        methods.add_method_mut ("set_url",|_,hr,url:String|{
            hr.url = url;Ok(())
        });
        methods.add_method_mut ("set_headers",|_,hr,headers:HashMap<String,String>|{
            for (key,value) in headers.iter() {
                hr.headers.insert(key.to_string(),value.to_string());
            }
            Ok(())
        });
        methods.add_method_mut ("set_body",|_,hr,body:String|{
            hr.body = to_static_str(body);Ok(())
        });
    }
}
//--------------------------------------------------------------------------------------------------